unit main;

interface

uses
  Classes, Controls, DB, ExtCtrls, Forms, Messages, StdCtrls, Windows, IfxConnection;

const
  WM_LOG = WM_USER + 1000;
  WM_THREADEND = WM_LOG + 1;

type
  TPoolDemoForm = class(TForm)
    buttonStartThreads: TButton;
    memoLog: TMemo;
    buttonDeletePools: TButton;
    groupPoolStats: TGroupBox;
    labelIdleCountCaption: TLabel;
    timerPoolStats: TTimer;
    labelExists: TLabel;
    labelIdleCountValue: TLabel;
    labelBusyCountCaption: TLabel;
    labelPeakCountCaption: TLabel;
    labelBusyCountValue: TLabel;
    labelPeakCountValue: TLabel;
    labelThreadsToStart: TLabel;
    editThreadsToStart: TEdit;
    connection: TIfxConnection;
    procedure FormCreate(Sender: TObject);
    procedure FormDestroy(Sender: TObject);
    procedure timerPoolStatsTimer(Sender: TObject);
    procedure buttonStartThreadsClick(Sender: TObject);
    procedure buttonDeletePoolsClick(Sender: TObject);
  private
    FTimeStart: DWORD;
    procedure Log(var Msg: TMessage); message WM_LOG;
    procedure ThreadComplete(var Msg: TMessage); message WM_THREADEND;
  end;

  TPoolTestThread = class(TThread)
  public
    procedure Execute; override;
  end;

var
  PoolDemoForm: TPoolDemoForm;

implementation

uses SysUtils, LXResourcePool, IfxQuery, IfxTable;

{$R *.DFM}

var
  ThreadList: TList;

procedure TPoolDemoForm.FormCreate(Sender: TObject);
begin
  timerPoolStatsTimer(Self);
end;

procedure TPoolDemoForm.FormDestroy(Sender: TObject);
var
  I: Integer;
begin
  for I := 0 to ThreadList.Count - 1 do
    TThread(ThreadList[I]).Terminate;
  for I := 0 to ThreadList.Count - 1 do
    TThread(ThreadList[I]).WaitFor;
  Application.ProcessMessages;
end;

procedure TPoolDemoForm.timerPoolStatsTimer(Sender: TObject);
begin
  with connection.GetPoolStats do
  begin
    if Exists then
      labelExists.Caption := 'Pool is in use' else
      labelExists.Caption := 'No active pool';
    labelIdleCountValue.Caption := IntToStr(IdleCount);;
    labelBusyCountValue.Caption := IntToStr(BusyCount);;
    labelPeakCountValue.Caption := IntToStr(PeakCount);;
  end;
end;

procedure TPoolDemoForm.buttonStartThreadsClick(Sender: TObject);
var
  I: Integer;
  ThreadsToAdd: Integer;
begin
  ThreadsToAdd := StrToInt(editThreadsToStart.Text);
  if ThreadList.Count = 0 then
    FTimeStart := GetTickCount;
  for I := 0 to ThreadsToAdd - 1 do
    ThreadList.Add(TPoolTestThread.Create(False));
end;

procedure TPoolDemoForm.buttonDeletePoolsClick(Sender: TObject);
begin
  TIfxConnection.DeletePools;
end;

procedure TPoolDemoForm.Log(var Msg: TMessage);
var
  S: string;
begin
  Integer(S) := Msg.WParam;
  memoLog.Lines.Add(S);
end;

procedure TPoolDemoForm.ThreadComplete(var Msg: TMessage);
begin
  ThreadList.Remove(Pointer(Msg.WParam));
  TThread(Msg.WParam).Free;
  if ThreadList.Count = 0 then
    memoLog.Lines.Add('Execution time of all threads ' +
      IntToStr(GetTickCount - FTimeStart) + ' ms');
end;

{ TPoolTestThread }

procedure TPoolTestThread.Execute;
var
  I: Integer;
  Conn: TIfxConnection;

  procedure Log(S: string);
  begin
    S := 'Thread ' + IntToStr(GetCurrentThreadId) + ': ' + S;
    PostMessage(PoolDemoForm.Handle, WM_LOG, Integer(S), 0);
    Pointer(S) := nil;
  end;

begin
  try
    Conn := TIfxConnection.Create(nil);
    try
      Conn.AssignParams(PoolDemoForm.connection);
      Conn.LoginPrompt := False;
      for I := 1 to 10 do
      begin
        if Terminated then Break;
        Conn.Open;
        try
          with TIfxQuery.Create(nil) do
            try
              Connection := Conn;
              SQL.Text := 'select * from customer';
              Open;
              FetchAll;
            finally
              Free;
            end;
          with TIfxTable.Create(nil) do
            try
              Connection := Conn;
              TableName := 'customer';
              Open;
              FetchAll;
            finally
              Free;
            end;
        finally
          Conn.Close;
        end;
        Log(Format('handled %d%%', [I*10]));
      end;
    finally
      Conn.Free;
    end;
  except
    on E: Exception do
      Log(E.Message);
  end;
  PostMessage(PoolDemoForm.Handle, WM_THREADEND, Integer(Self), 0);
end;


initialization
  ThreadList := TList.Create;

finalization
  FreeAndNil(ThreadList);

end.
